require 'busted.runner'()

local assert = require 'spec.tools.assert'
local bn = require 'nelua.utils.bn'

local n = bn.parse
local d = bn.fromdec
local h = bn.fromhex
local b = bn.frombin

describe("Nelua BN should work for", function()

it("big numbers", function()
  assert.is.equal('0', n(0):todec())
  assert.is.equal('0', n(-0):todec())
  assert.is.equal('1', n(1):todec())
  assert.is.equal('-1',n(-1):todec())
  assert.is.equal('0.5', bn.todecsci(0.5))
  assert.is.equal('-0.5', bn.todecsci(-0.5))
  assert.is.equal('0.30000000000000004', bn.todecsci(.1+.2))
  assert.is.equal('1000', bn.todecsci(1000))
  assert.is.equal('0.14285714285714285', bn.todecsci(n(1)/ n(7)))
  assert.is.equal('1.4285714285714286', bn.todecsci(n(10)/ n(7)))
  assert.is.equal('-0.14285714285714285', bn.todecsci(n(-1)/ n(7)))
  assert.is.equal('-1.4285714285714286', bn.todecsci(n(-10)/ n(7)))
  assert.is.equal('14.285714285714286', bn.todecsci(n(100)/ n(7)))
  assert.is.equal('-14.285714285714286', bn.todecsci(n(-100)/ n(7)))
  assert.is.equal('0.014285714285714287', bn.todecsci(n('0.1')/ n(7)))
  assert.is.equal('-0.014285714285714287', bn.todecsci(n('-0.1')/ n(7)))
  assert.is.equal('0.0001', bn.todecsci(0.0001))
  assert.is.equal('1e-05', bn.todecsci('0.00001'))
  assert.is.equal('0.0001', bn.todecsci(0.0001))
  assert.is.equal('1.4285714285714285e-05', bn.todecsci(n(1) / n(70000)))
  assert.is.equal('1.4285714285714285e-05', bn.todecsci(1 / 70000))
  assert.is.equal(1, n(1):compress())
  assert.is.equal(0.5, bn.compress(0.5))
  assert.is.equal(h'ffffffffffffffff', h'ffffffffffffffff':compress())
end)

it("regular number conversion", function()
  assert.is.same(n(0):tonumber(), 0)
  assert.is.same(n(1):tonumber(), 1)
  assert.is.same(n(-1):tonumber(), -1)
  assert.is.same(n(123456789):tonumber(), 123456789)
end)

it("decimal number conversion", function()
  assert.is.same(d'0', n(0))
  assert.is.same(d'1', n(1))
  assert.is.same(d'-1', n(-1))
  assert.is.same(d'4096', n(4096))
  assert.is.same(d'65536', n(65536))
  assert.is.same(bn.todecsci('12345.6789'), '12345.6789')
  assert.is.same(bn.todecsci('-12345.6789'), '-12345.6789')

  assert.is.equal('0', bn.todecsci(0))
  assert.is.equal('0', bn.todecsci(-0))
  assert.is.equal('1', bn.todecsci(1))
  assert.is.equal('-1',bn.todecsci(-1))
  assert.is.equal('0.5', bn.todecsci(0.5))
  assert.is.equal('-0.5', bn.todecsci(-0.5))
  assert.is.equal('0.30000000000000004', bn.todecsci(.1+.2))
  assert.is.equal('0.30000000000000004', bn.todecsci(n(.1)+n(.2)))
  assert.is.equal('0.30000000000000004', bn.todecsci(n('.1')+n('.2')))
  assert.is.equal('1000', bn.todecsci(1000))
end)

it("hexadecimal conversion", function()
  assert.is.same(h'0', n(0))
  assert.is.same(h'-0', n(0))
  assert.is.same(h'1', n(1))
  assert.is.same(h'-1', n(-1))
  assert.is.same(h'1234567890', n(0x1234567890))
  assert.is.same(h'abcdef', n(0xabcdef))
  assert.is.same(h'ffff', n(0xffff))
  assert.is.same(h'-ffff', n(-0xffff))
  assert.is.same(h'ffffffffffffffff', d'18446744073709551615')
  assert.is.same(h'-ffffffffffffffff', d'-18446744073709551615')

  assert.is.same(h'1234567890abcdef':tohex(), '1234567890abcdef')
  assert.is.same(h'0':tohex(), '0')
  assert.is.same(h'ffff':tohex(), 'ffff')
  assert.is.same(h'-ffff':tohex(64), 'ffffffffffff0001')
end)

it("binary conversion", function()
  assert.is.same(b'0', n(0))
  assert.is.same(b'1', n(1))
  assert.is.same(b'10', n(2))
  assert.is.same(b'11', n(3))
  assert.is.same(b'-11', n(-3))
  assert.is.same(b'11111111', n(255))
  assert.is.same(b'100000000', n(256))


  assert.is.same(b'11':tobin(), '11')
  assert.is.same(b'10':tobin(), '10')
  assert.is.same(b'1':tobin(), '1')
  assert.is.same(b'0':tobin(), '0')
  assert.is.same(h'-1':tobin(8), '11111111')
end)

it("scientific notation", function()
  assert.is.equal('0.14285714285714285', bn.todecsci(n(1)/ n(7)))
  assert.is.equal('1.4285714285714286', bn.todecsci(n(10)/ n(7)))
  assert.is.equal('-0.14285714285714285', bn.todecsci(n(-1)/ n(7)))
  assert.is.equal('-1.4285714285714286', bn.todecsci(n(-10)/ n(7)))
  assert.is.equal('14.285714285714286', bn.todecsci(n(100)/ n(7)))
  assert.is.equal('-14.285714285714286', bn.todecsci(n(-100)/ n(7)))
  assert.is.equal('0.014285714285714287', bn.todecsci(0.1/ n(7)))
  assert.is.equal('-0.014285714285714287', bn.todecsci(-0.1/ n(7)))
  assert.is.equal('0.0001', bn.todecsci(0.0001))
  assert.is.equal('1e-05', bn.todecsci('0.00001'))
  assert.is.equal('0.0001', bn.todecsci(0.0001))
  assert.is.equal('1.4285714285714285e-05', bn.todecsci(n(1) / n(70000)))
  assert.is.equal('1.4285714285714285e-05', bn.todecsci(1 / 70000))
end)

end)
